import Taro from '@tarojs/taro'
import { useState, useCallback, useEffect } from 'react'
import { DEFAULT_TAKE } from '@CONSTANTS/common'
import { useSelector } from 'react-redux'
import { RootStateITF } from '@REDUXITF/index'

interface UsePaginationListApiParams {
  dataKey: string;
  fetchApi: (params: string | Record<string, unknown>) => Promise<any>;
  payload?: Record<string, unknown>
}

interface UsePaginationListApiResult<T> {
  loading: boolean;
  refreshing: boolean;
  dataList: T[];
  canLoadMore: boolean;
  fetchData: (skip: number) => Promise<void>;
  onRefresh: () => void;
  onEndReached: () => void;
}

const usePaginationListApi = <T>({
  payload, fetchApi, dataKey,
}: UsePaginationListApiParams): UsePaginationListApiResult<T> => {
  const [loading, setLoading] = useState(true)
  const [refreshing, setRefreshing] = useState(true)
  const [dataList, setDataList] = useState<T[]>([])
  const [canLoadMore, setCanLoadMore] = useState(true)
  const userId = useSelector<RootStateITF, string | undefined>(state => state.profile.user?.p8Id)

  const fetchData = useCallback(
    async skip => {
      try {
        setLoading(true)
        const params = { skip, take: DEFAULT_TAKE, ...(payload || {}) }
        const response = await fetchApi?.(params)
        const list = dataKey ? response[dataKey] : response
        setDataList(preList => (skip === 0 ? list : preList.concat(list)))
        setCanLoadMore(list.length >= DEFAULT_TAKE)
      } catch (error) {
        Taro.showToast({
          title: error.message || error,
          icon: 'none'
        })
      } finally {
        setLoading(false)
        setRefreshing(false)
      }
    },
    [payload, fetchApi, dataKey]
  )

  const onRefresh = useCallback(
    () => {
      setLoading(true)
      setRefreshing(true)
      fetchData(0)
    },
    [fetchData]
  )

  const onEndReached = useCallback(
    () => {
      if (!canLoadMore || loading) return
      const skip = dataList?.length
      fetchData(skip)
    },
    [dataList, canLoadMore, fetchData, loading]
  )

  const initFetch = useCallback(
    async () => {
      if (!userId) return
      fetchData(0)
    },
    [fetchData, userId]
  )

  useEffect(() => {
    initFetch()
  }, [initFetch])

  return {
    loading, refreshing, dataList, canLoadMore, fetchData, onRefresh, onEndReached
  }
}

export default usePaginationListApi
